package com.dingding.order.common.util;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.Consts;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSONObject;
import com.dingding.common.core.config.AmapConfig;
import com.dingding.common.core.util.JSONUtil;
import com.dingding.order.common.util.dto.OrderMileageDTO;

/**
 * 
 * @ClassName: GetDistanceUtil 
 * @Description: 经纬度转换成距离工具类
 * @author cheshaowei
 * @date 2015-10-9 下午04:51:51
 */
public class MapUtil extends AmapConfig {

	/**
	 * @Title: getSingleDistance
	 * @Description: 根据两点的经纬度获取下单距离（下单获取距离）
	 * @author yuHaiQing
	 * @since V2.5.7
	 * @return OrderMileageDTO 
	 * 
	 */
	public static OrderMileageDTO getSingleDistance(double lng1, double lat1, double lng2, double lat2) {

		// 两点之前的乘车距离(米)
		int distance = 0;
		// 城市编码
		String cityNo = null;
		// 预估订单时长(秒)
		int duration = 0;
		// 城市名称
		String cityName = null;
		// 打车费用(分)
		int taxiCost = 0;

		OrderMileageDTO orderMileageDTO = new OrderMileageDTO();

		CloseableHttpClient client = HttpClients.createDefault();

		// 请求地址
		String url = "http://restapi.amap.com/v3/direction/driving";

		// 创建HTTPPost对象
		HttpPost httpPost = new HttpPost(url);

		// 对请求参数进行封装
		List<NameValuePair> params = new ArrayList<NameValuePair>();

		// 出发点，经度在前，纬度在后，经度和纬度用","分割，经纬度小数点后不得超过6位。
		params.add(new BasicNameValuePair("origin", lng1 + "," + lat1));
		// 目的地，经度在前，纬度在后，经度和纬度用","分割，经纬度小数点后不得超过6位。
		params.add(new BasicNameValuePair("destination", lng2 + "," + lat2));
		// 返回结果详略: base:返回基本信息；all：返回全部信息
		params.add(new BasicNameValuePair("extensions", "all"));
		// 返回数据格式类型(json、xml)
		params.add(new BasicNameValuePair("output", "json"));
		// 驾车选择策略 0.速度优先（时间）1.费用优先（不走收费路段的最快道路） 2.距离优先 3.不走快速路 4.躲避拥堵
		// 5.多策略（同时使用速度优先、费用优先、距离优先三个策略计算路径） 6.不走高速 7.不走高速且避免收费 8.躲避收费和拥堵
		// 9.不走高速且躲避收费和拥堵
		params.add(new BasicNameValuePair("strategy", AmapConfig.STRATEGY));
		// 用户唯一标识
		params.add(new BasicNameValuePair("key", AmapConfig.ACCESS_KEY));

		try {
			// 添加请求参数到请求对象
			httpPost.setEntity(new UrlEncodedFormEntity(params, Consts.UTF_8));

			// 执行http请求
			CloseableHttpResponse httpResponse = client.execute(httpPost);

			// 如果状态码为200 ok
			if (httpResponse.getStatusLine().getStatusCode() == 200) {

				// 读取返回的数据
				String strResult = EntityUtils.toString(httpResponse.getEntity());

				// 将string转为json
				JSONObject jsonObject = JSONObject.parseObject(strResult);

				// 获取两点之间的距离（驾车最近距离 单位：米）
				distance = getDisnce(jsonObject);
				// 获取城市编号
				cityNo = getCityNo(jsonObject);
				// 获取城市名称
				cityName = getCityName(jsonObject);
				// 订单时长
				duration = getDuration(jsonObject);
				// 打车费用
				taxiCost = getTaxiCost(jsonObject);
				
				orderMileageDTO.setCitycode(cityNo);	// 城市编码(出发城市)
				orderMileageDTO.setDistance(distance);	// 里程
				orderMileageDTO.setCityName(cityName);	// 城市名称(出发城市)
				orderMileageDTO.setDuration(duration);	// 里程时长(秒)
				orderMileageDTO.setTaxiCost(taxiCost);	// 打车费用(出租车)
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		return orderMileageDTO;
	}

	/**
	 * 
	 * @Title: getCityNo 
	 * @Description: 获取城市编号
	 * @param jsonObject 高德返回JSON数据
	 * @author YHQ 
	 * @return int    返回类型
	 * 
	 */
	private static int getDisnce(JSONObject jsonObject){
		
		// 默认距离0（其他）
		int distance = 0;
		
		try {
			// 获取城市编码
			distance = jsonObject.getJSONObject("route").getJSONArray("paths").getJSONObject(0).getInteger("distance");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return distance;
	}
	
	/**
	 * 
	 * @Title: getCityNo 
	 * @Description: 获取城市编号
	 * @param jsonObject 高德返回JSON数据
	 * @author YHQ 
	 * @return int    返回类型
	 * 
	 */
	private static String getCityNo(JSONObject jsonObject){
		
		// 默认城市编号9999（其他）
		String cityNo = "010";
		
		try {
			// 获取城市编码
			cityNo = jsonObject.getJSONObject("route").getJSONArray("paths").getJSONObject(0).getJSONArray("steps")
					.getJSONObject(0).getJSONArray("cities").getJSONObject(0).getString("citycode");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return cityNo;
	}
	
	/**
	 * 
	 * @Title: getCityName 
	 * @Description: 获取城市名称
	 * @param jsonObject 高德返回JSON数据
	 * @author YHQ 
	 * @return String    返回类型
	 */
	private static String getCityName(JSONObject jsonObject){
		
		String cityName = "其他";
		
		try {
			cityName = jsonObject.getJSONObject("route").getJSONArray("paths").getJSONObject(0).getJSONArray("steps")
					.getJSONObject(0).getJSONArray("cities").getJSONObject(0).getString("name");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return cityName;
	}
	
	/**
	 * 
	 * @Title: getDuration 
	 * @Description: 预估订单时长
	 * @param jsonObject  高德返回JSON数据
	 * @author YHQ 
	 * @return int    返回类型
	 * 
	 */
	private static int getDuration(JSONObject jsonObject){
		
		int duration = 0;
		
		try {
			duration = jsonObject.getJSONObject("route").getJSONArray("paths").getJSONObject(0).getInteger("duration");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return duration;
	}
	
	/**
	 * 
	 * @Title: getTaxiCost 
	 * @Description: 获取出租车预估金额
	 * @param jsonObject 高德返回JSON数据
	 * @author YHQ 
	 * @return int    返回类型
	 * 
	 */
	public static int getTaxiCost(JSONObject jsonObject){
		
		int taxiCost = 0;
		
		try {
			taxiCost = jsonObject.getJSONObject("route").getDouble("taxi_cost").intValue() * 1000;
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return taxiCost;
	}
	
	public static void main(String[] args) {

		OrderMileageDTO orderMileageDTO = getSingleDistance(116.50425, 39.77798, 116.50425, 39.77798);

		System.out.println("计算距离价格  " + JSONUtil.toJSON(orderMileageDTO));

	}

}
